<script setup lang="ts">
import {computed, ref} from 'vue'
import {useWindowSize} from '@vueuse/core'
import {FormRules} from 'naive-ui'
import {
  StnIpt,
  IptTypeConst,
  useTipStore,
  TipMessageTypeConst,
} from 'st-ui-vue3-navie'
import {ResObjPropNameConst} from 'st-common-req'
import {useUserApi} from '@user'
import {ResponsiveDialogForm} from '@components'
import {UserFormDefault} from '../consts/user-form-default'

/**
 * 组件参数
 */
const {
  isAdd = false,
} = defineProps<{
  // 是否为新增用户信息
  isAdd?: boolean;
}>()

/**
 * 组件双向绑定
 */
// 是否显示对话框
const show = defineModel<boolean>('show')
// 表单数据
const form = defineModel<typeof UserFormDefault>('form')
// 关闭处理函数
const closeHandler = defineModel<() => void>('closeHandler')

// 窗口大小
const {width: windowWidth} = useWindowSize()
// 对话框宽度
const dialogWidth = computed(() => {
  if (windowWidth.value <= 425) return 300
  if (windowWidth.value <= 768) return 500
  return 700
})

// 表单验证规则
const rules: FormRules = {
  username: {
    required: true,
    message: '请输入用户名',
    trigger: 'blur',
  },
  nickname: {
    required: true,
    message: '请输入昵称',
    trigger: 'blur',
  },
  password: {
    required: isAdd,
    message: '请输入密码',
    trigger: 'blur',
    min: 6,
    max: 20,
  },
  email: {
    required: true,
    message: '请输入邮箱',
    trigger: 'blur',
    pattern: /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
  },
  phone: {
    required: true,
    message: '请输入手机号',
    trigger: 'blur',
    pattern: /^1[3456789]\d{9}$/,
  },
}

// 性别选项
const genderOptions = [
  {
    label: '未知',
    value: 0,
  },
  {
    label: '男',
    value: 1,
  },
  {
    label: '女',
    value: 2,
  },
]

// 状态选项
const statusOptions = [
  {
    label: '启用',
    value: 1,
  },
  {
    label: '禁用',
    value: 0,
  },
]

// 表单加载状态
const formLoading = ref(false)

// 用户 API
const userApi = useUserApi()

/**
 * 保存用户信息
 */
const saveUserInfo = async (formData: typeof UserFormDefault) => {
  formLoading.value = true
  try {
    if (isAdd) {
      const res = await userApi.addUser(formData)
      if (res[ResObjPropNameConst.STATUS]) {
        useTipStore().message('新增用户成功', TipMessageTypeConst.SUCCESS)
        show.value = false
        closeHandler.value?.()
      } else {
        useTipStore().message(res[ResObjPropNameConst.MESSAGE], TipMessageTypeConst.ERROR)
      }
    } else {
      const res = await userApi.updateUser(formData)
      if (res[ResObjPropNameConst.STATUS]) {
        useTipStore().message('更新用户成功', TipMessageTypeConst.SUCCESS)
        show.value = false
        closeHandler.value?.()
      } else {
        useTipStore().message(res[ResObjPropNameConst.MESSAGE], TipMessageTypeConst.ERROR)
      }
    }
  } finally {
    formLoading.value = false
  }
}
</script>

<template>
  <ResponsiveDialogForm
    v-model:show="show"
    :title="isAdd ? '新增用户' : '编辑用户'"
    :width="dialogWidth"
    :form="form"
    :rules="rules"
    :loading="formLoading"
    :save-handler="saveUserInfo"
  >
    <StnIpt
      label="用户名"
      v-model:value="form.username"
      :type="IptTypeConst.TEXT"
      placeholder="请输入用户名"
      required
    />
    <StnIpt
      label="昵称"
      v-model:value="form.nickname"
      :type="IptTypeConst.TEXT"
      placeholder="请输入昵称"
      required
    />
    <StnIpt
      label="密码"
      v-model:value="form.password"
      :type="IptTypeConst.PASSWORD"
      placeholder="请输入密码"
      :required="isAdd"
    />
    <StnIpt
      label="邮箱"
      v-model:value="form.email"
      :type="IptTypeConst.TEXT"
      placeholder="请输入邮箱"
      required
    />
    <StnIpt
      label="手机号"
      v-model:value="form.phone"
      :type="IptTypeConst.TEXT"
      placeholder="请输入手机号"
      required
    />
    <StnIpt
      label="性别"
      v-model:value="form.gender"
      :type="IptTypeConst.SELECT"
      :options="genderOptions"
      placeholder="请选择性别"
      clearable
    />
    <StnIpt
      label="状态"
      v-model:value="form.status"
      :type="IptTypeConst.SELECT"
      :options="statusOptions"
      placeholder="请选择状态"
      clearable
    />
  </ResponsiveDialogForm>
</template> 